home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '93 / Hacks '93 / Dude NOT! / AttackDude.c next >
Encoding:
C/C++ Source or Header  |  1993-06-18  |  4.0 KB  |  170 lines  |  [TEXT/MPS ]

  1. /*
  2.  *    AttackDude.c - Fix autoremounter behavior.
  3.  *
  4.  *    Mark D. Rustad    93/06/16.
  5.  *
  6.  *    This extension (hack) changes the behavior of autoremounter
  7.  *    to never send broadcast echo packets (imagine what that does
  8.  *    to large ethernets or token rings). It is called “Dude NOT!”
  9.  *    because all the trouble is caused by the 'dude' Gestalt selector
  10.  *    function.
  11.  *
  12.  *    Installation of this extension will tend to prevent autoremounter
  13.  *    from remounting volumes on very small networks when you plug into
  14.  *    the network after coming out of sleep. Of course, you should
  15.  *    always connect the network BEFORE coming out of sleep to ensure
  16.  *    that a unique AppleTalk address is acquired... So, if you never
  17.  *    use a large network and like to plug a running maching into active
  18.  *    networks, this hack is not for you.
  19.  *
  20.  *    This hack also demonstrates the creation of a stand-alone code
  21.  *    resource with it’s own A5 world and no assembly and no _datainit
  22.  *    junk. Of course, I do need to use GCC to do this and a couple inlines,
  23.  *    but I like it, because compilers can generate smaller, faster code
  24.  *    if you use A5 worlds rather than passing global variable pointers
  25.  *    around all over (I wish I had discovered this technique years ago).
  26.  *    You can use the same technique with MPW C if you link with one tiny
  27.  *    assembly routine (provided in the comments later).
  28.  *
  29.  *    This hack turned out so simple I didn’t even need any globals, so in
  30.  *    this case things could be simplified by NOT setting up the A5 world,
  31.  *    but then this hack couldn’t demonstrate the efficient, convenient use
  32.  *    of A5 globals in a stand-alone code resource.
  33.  */
  34.  
  35. #define    SystemSixOrLater 1
  36.  
  37. #include <Types.h>
  38. #include <Memory.h>
  39. #include <Resources.h>
  40. #include <GestaltEqu.h>
  41.  
  42. /*    The following inline swaps A5 values */
  43.  
  44. #pragma parameter __D0 SwapA5 (__D0)
  45. void    *SwapA5(void *) = {0xC18D};    /* Exg D0, A5 */
  46.  
  47. long    *GetA5(void) = 0x200D;
  48.  
  49. /*    Forward declarations */
  50.  
  51. static int    GetInitSize(long *p);
  52. static void    _A5Init(void);
  53. static void    FixRemounter(void);
  54.  
  55.  
  56. void    Init(void)
  57. {
  58.     long    *p = (long *)&_A5Init;
  59.     char    *gptr;
  60.     long    *oldA5;
  61.  
  62.     if (GetInitSize(p))    /* This verifies that no globals were initialized non-zero */
  63.     {
  64.         DebugStr((unsigned char *)"\pInit data present");
  65.         return;
  66.     }
  67.  
  68.     /* Allocate space for globals */
  69.  
  70.     if ((gptr = (char *)NewPtrSysClear(*p + 32)) == 0)
  71.         return;
  72.  
  73.     oldA5 = SwapA5(gptr + *p);    /* Set up A5 for globals */
  74. //    *GetA5() = *oldA5;    /* Uncomment this line if you want to inherit qd globals */
  75.  
  76.     /* Do something */
  77.     FixRemounter();
  78.  
  79.     SwapA5(oldA5);        /* Restore A5 */
  80.     return;
  81. }
  82.  
  83.  
  84. /*
  85.  *    GetInitSize - Return size of initialization records.
  86.  *
  87.  *    This function is required simply for a successful build
  88.  *    with gcc since it generates code that will fail to link.
  89.  *    This is due to the fact that the pointer is really pointing
  90.  *    into code space. Adding this function prevented a gcc
  91.  *    transformation that resulted in unlinkable code.
  92.  */
  93.  
  94. static int    GetInitSize(long *p)
  95. {
  96.     return p[2];
  97. }
  98.  
  99.  
  100. /*
  101.  *    _A5Init - Dummy function to permit global data declarations.
  102.  *
  103.  *    Using a C function this way only works when compiled using GCC under
  104.  *    MPW. If using MPW C, a tiny assembly equivalent, as follows, will
  105.  *    work:
  106.  *            Proc
  107.  *            Export    _A5Init
  108.  *    _A5Init    DC.W    0
  109.  *            EndProc
  110.  *            End
  111.  */
  112.  
  113. void    _A5Init(void)
  114. {
  115. }
  116.  
  117.  
  118. /*    Here is my global, even though I don’t really need it */
  119.  
  120. static ProcPtr    OrigDudeFunc;
  121.  
  122.  
  123. /*
  124.  *    FixRemounter - Fix Autoremounter.
  125.  */
  126.  
  127. static void    FixRemounter(void)
  128. {
  129.     OSErr    result;
  130.     pascal OSErr    MyDudeFunc(long, long *);
  131.  
  132.     result = ReplaceGestalt('dude', (ProcPtr)MyDudeFunc, &OrigDudeFunc);
  133.     switch (result)
  134.     {
  135.     case gestaltUndefSelectorErr:
  136.         return;
  137.  
  138.     case gestaltLocationErr:
  139.     case gestaltUnknownErr:
  140.     default:
  141.         return;
  142.  
  143.     case noErr:
  144.         break;
  145.     }
  146.  
  147.     /* Replaced dude (hopefully before it had been invoked) */
  148.  
  149.     {
  150.         Handle    hdl;
  151.  
  152.         hdl = RecoverHandle((void *)&Init);
  153.         DetachResource(hdl);
  154.     }
  155. }
  156.  
  157.  
  158. /*
  159.  *    MyDudeFunc - My replacement for the 'dude' gestalt routine.
  160.  */
  161.  
  162. pascal OSErr    MyDudeFunc(long sel, long *result)
  163. {
  164.     OSErr    err;
  165.  
  166.     err = Gestalt('atlk', result);
  167.     *result = (*result == 0) + 16;
  168.     return err;
  169. }
  170.